if (!window.org) window.org = {};
if (!org.dreamwork) org.dreamwork = {};
if (!org.dreamwork.js) org.dreamwork.js = {};
if (!org.dreamwork.js.util) org.dreamwork.js.util = {};

org.dreamwork.js.util.Calendar = function () {
    var time = arguments [0] ? arguments [0] : new Date ();
    var today = new Date ();
    var panel;
    var locale = org.dreamwork.js.util.Util.locale.toUpperCase () || "DEFAULT";
    var fontSize = "12px";
    var fontFamily = "Verdana";
    var body = null, header = null, footer = null;
    
    var self = this;
    var today_title = [];
    var Titles = [];
    var parent;
    var year_block, month_block;
    var underlay;
    var ie6 = (navigator.userAgent.indexOf ("MSIE 6.0") > -1);
    var selectedDate;

    this.date = today;
    this.today = today;
    // events
    var on_close_events = [];

    today_title ["ZH-CN"] = "今天";
    today_title ["DEFAULT"] = "Today";

    Titles.year = [];
    Titles.year["ZH-CN"] = {prev: "上一年", next: "下一年"};
    Titles.year["DEFAULT"] = {prev: "Previous Year", next: "Next Year"};
    Titles.month = [];
    Titles.month ["ZH-CN"] = { prev: "上个月", next : "下个月" };
    Titles.month ["DEFAULT"] = {prev: "Previous Month", next: "Next Month"};
    Titles.button = [];
    Titles.button ["ZH-CN"] = "取消";
    Titles.button ["DEFAULT"] = "Cancel";
    Titles.clear = [];
    Titles.clear ["ZH-CN"] = "清除";
    Titles.clear ["DEFAULT"] = "Clear";

    panel = document.getElementById ("org.dreamwork.js.util.Calendar$Panel");
    if (!panel) buildPanel ();

    // public method
    this.setMonth = function (month) {
        time.setMonth (month);
        clearDateGrid ();
        buildDateGrid (body, month);
    };

    this.close = function () {
        for (var i = 0; i < on_close_events.length; i ++) on_close_events [i] ();
        panel.style.display = "none";
        if (underlay) underlay.style.display = "none";
    };

    this.cancel = function () {
        panel.style.display = "none";
        if (underlay) underlay.style.display = "none";
    };

    this.install = function (element) {
        if (typeof element == "string") element = document.getElementById (element);
        element.onclick = function () {
            parent = element;
            var text = "";
            var tagName = element.tagName.toUpperCase ();
            if (tagName == "INPUT" || tagName == "TEXTAREA") text = element.value;
            else text = element.innerHTML;

            if (Date.isDateString (text))
            {
                var date = Date.parseDate (text);
                time.setFullYear (date.getFullYear ());
                time.setMonth (date.getMonth ());
                time.setDate (date.getDate ());
            }
            selectedDate = text;
            getPosition (element);
            findSelectedDate ();
        };
    };

    this.shown = function () {
        //		header.style.width = body.clientWidth;
        //		footer.style.width = body.clientWidth;
        //		panel.style.width = body.clientWidth;
        //		panel.style.height = header.scrollHeight + footer.scrollHeight + body.scrollHeight;

        var height = panel.scrollHeight;
        var pos = {x:parseInt (panel.style.left), y:parseInt (panel.style.top)};
        if (pos.y + height >= document.body.clientHeight) {
            pos.y -= height;
            panel.style.top = pos.y + "px";
        }
    };

    this.deleteValue = function () {
        if (!parent) {
            this.cancel ();
            return;
        }

        var tagName = parent.tagName.toUpperCase ();
        if (tagName == "INPUT" || tagName == "TEXTAREA") {
            parent.value = "";
        } else {
            parent.innerHTML = "";
        }
        this.cancel ();
    };

    this.addOnCloseEvent = function (event) {
        on_close_events.push (event);
    };
    this.setTime = function (date) {
        if (date instanceof Date) time.copy (date);
    };
    this.getPanel = function () {
        return panel;
    };
    this.callback = function () {
    };

    // private method
    function getPosition (element) {
        var pos = org.dreamwork.js.util.Util.getPosition (element);
        var clientHeight = element.offsetHeight;
        pos.y += clientHeight;

        panel.style.display = "block";
        panel.style.left = pos.x + "px";
        panel.style.top = pos.y + "px";

        var height = panel.scrollHeight;
        if (pos.y + height >= document.body.clientHeight + document.body.scrollTop) {
            pos.y -= clientHeight;
            pos.y -= height;
            panel.style.top = pos.y + "px";
        }
        if (underlay) {
            underlay.style.display = "block";
            underlay.style.left = panel.style.left;
            underlay.style.top = panel.style.top;
            underlay.style.width = (panel.clientWidth - 1) + "px";
            underlay.style.height = (panel.clientHeight - 1) + "px";
        }
    }

    function findSelectedDate () {
        for (var i = 0; i < body.rows.length; i ++) {
            var row = body.rows [i];
            for (var j = 0; j < row.cells.length; j ++) {
                var cell = row.cells [j];
                if (cell.date && cell.date.format () == selectedDate) {
                    cell.style.border = "1px solid red";
                } else {
                    cell.style.border = "";
                }
            }
        }
    }

    function buildPanel () {
        panel = document.createElement ("div");
        panel.id = "org.dreamwork.js.util.Calendar$Panel";
        panel.style.position = "absolute";
        panel.style.display = "none";
        panel.style.backgroundColor = "white";
        panel.style.fontSize = fontSize;
        panel.style.fontFamily = fontFamily;
        panel.style.border = "1px solid black";
        panel.style.zIndex = 1000;
        panel.style.width = "200px";
        //		panel.style.height = "170px";
        document.body.appendChild (panel);

        if (ie6) {
            underlay = document.createElement ("iframe");
            underlay.style.position = "absolute";
            underlay.style.display = "none";
            underlay.style.backgroundColor = "white";
            underlay.style.fontSize = fontSize;
            underlay.style.fontFamily = fontFamily;
            underlay.style.zIndex = 999;
            document.body.appendChild (underlay);
        }

        createTable ();
        on_close_events.push (function () {
            if (!parent) return;
            var tagName = parent.tagName.toUpperCase ();
            if (tagName == "INPUT" || tagName == "TEXTAREA") parent.value = self.date.format ();
            else parent.innerHTML = self.date.format ();
        });
    }

    function createTable () {
        header = createHeader ();
        body = createBody ();
        footer = buildFooter ();

        panel.appendChild (header);
        panel.appendChild (body);
        panel.appendChild (footer);
    }

    function createHeader () {
        var header = document.createElement ("table");
        header.style.fontSize = fontSize;
        header.style.fontFamily = fontFamily;
        header.cellPadding = 3;
        header.cellSpacing = 1;
        header.border = 0;
        var row = header.insertRow (0);
        buildPrevYear (row);
        buildPrevMonth (row);
        buildYearArea (row);
        buildMonthArea (row);
        buildNextMonth (row);
        buildNextYear (row);
        return header;
    }

    function buildPrevYear (row) {
        var cell = row.insertCell (0);
        cell.innerHTML = "&lt;&lt;";
        cell.nowrap = true;
        cell.width = 10;
        cell.title = Titles.year [locale].prev;
        cell.style.cursor = "pointer";
        cell.onclick = function () {
            time.add (Date.YEAR, -1);
            clearDateGrid ();
            buildDateGrid (body);
            year_block.innerHTML = time.getFullYear ();
        };
        /*
         cell.style.borderLeft = "1px solid white";
         cell.style.borderTop = "1px solid white";
         cell.style.borderRight = "1px solid black";
         cell.style.borderBottom = "1px solid black";
         */
        cell.style.border = "1px solid black";
    };

    function buildPrevMonth (row) {
        cell = row.insertCell (1);
        cell.nowrap = true;
        cell.width = 10;
        cell.innerHTML = "&lt;";
        cell.title = Titles.month [locale].prev;
        cell.style.cursor = "pointer";
        cell.onclick = function () {
            time.add (Date.MONTH, -1);
            clearDateGrid ();
            buildDateGrid (body);
            year_block.innerHTML = time.getFullYear ();
            month_block.innerHTML = Date.MonthTitles[locale] [time.getMonth ()];
        };
        cell.style.border = "1px solid black";
    }

    function buildYearArea (row) {
        cell = row.insertCell (2);
        cell.width = "50%";
        cell.nowrap = true;
        cell.align = "center";
        cell.style.border = "1px solid #CCCCFF";
        year_block = document.createElement ("span");
        year_block.id = "_$_year_block_$_";
        year_block.style.cursor = "pointer";
        year_block.innerHTML = time.getFullYear ();
        cell.appendChild (year_block);

        var year_editor = document.createElement ("input");
        year_editor.id = "_$_year_editor_$_";
        year_editor.style.display = "none";
        cell.appendChild (year_editor);

        year_block.onclick = function (event) {
            if (!event) event = window.event;
            if (!event.target) event.target = event.srcElement;
            year_editor.style.width = "100%";
            year_editor.value = year_block.innerHTML;
            year_editor.style.display = "block";
            year_block.style.display = "none";
        };
        year_editor.onkeyup = function (event) {
            if (!event) event = window.event;
            if (!event.target) event.target = event.srcElement;
            if (event.keyCode == 27) {// esc
                year_editor.style.display = "none";
                year_block.style.display = "block";
            } else if (event.keyCode == 13) { // enter
                year_editor.style.display = "none";
                year_block.style.display = "block";
                if (Number.isInteger (year_editor.value)) {
                    year_block.innerHTML = year_editor.value;
                    time.setFullYear (year_editor.value);
                    clearDateGrid ();
                    buildDateGrid (body);
                }
            }
        };
        year_editor.onblur = function () {
            if (Number.isInteger (year_editor.value)) {
                year_block.innerHTML = year_editor.value;
                time.setFullYear (year_editor.value);
                clearDateGrid ();
                buildDateGrid (body);
            }
            year_editor.style.display = "none";
            year_block.style.display = "block";
        };
    }

    function buildMonthArea (row) {
        cell = row.insertCell (3);
        cell.width = "50%";
        cell.nowrap = true;
        cell.align = "center";
        cell.style.border = "1px solid #CCCCFF";
        month_block = document.createElement ("span");
        month_block.id = "_$_month_block_$_";
        month_block.style.cursor = "pointer";
        month_block.innerHTML = Date.MonthTitles [locale][time.getMonth ()];
        cell.appendChild (month_block);

        var month_editor = document.createElement ("select");
        month_editor.id = "_$_month_editor_$_";
        month_editor.style.fontSize = fontSize;
        month_editor.style.fontFamily = fontFamily;

        for (var i = 0; i < Date.MonthTitles[locale].length; i ++) {
            var option = document.createElement ("option");
            option.value = i;
            option.text = Date.MonthTitles[locale] [i];
            if (time.getMonth () == i) option.selected = true;
            month_editor.options [month_editor.options.length ++] = option;
        }
        month_editor.style.display = "none";

        month_block.onclick = function () {
            month_editor.style.display = "block";
            month_editor.focus ();
            month_block.style.display = "none";
        };
        month_editor.onchange = function () {
            month_block.style.display = "block";
            month_block.innerHTML = month_editor.options [month_editor.selectedIndex].text;
            self.setMonth (month_editor.value);
            month_editor.style.display = "none";
        };
        month_editor.onblur = function () {
            month_block.style.display = "block";
            month_block.innerHTML = month_editor.options [month_editor.selectedIndex].text;
            self.setMonth (month_editor.value);
            month_editor.style.display = "none";
        };

        cell.appendChild (month_editor);
    }

    function buildNextMonth (row) {
        cell = row.insertCell (4);
        cell.innerHTML = "&gt;";
        cell.nowrap = true;
        cell.width = 10;
        cell.style.cursor = "pointer";
        cell.title = Titles.month [locale].next;
        cell.onclick = function () {
            time.add (Date.MONTH, 1);
            clearDateGrid ();
            buildDateGrid (body);
            year_block.innerHTML = time.getFullYear ();
            month_block.innerHTML = Date.MonthTitles[locale] [time.getMonth ()];
        };
        cell.style.border = "1px solid black";
    }

    function buildNextYear (row) {
        cell = row.insertCell (5);
        cell.nowrap = true;
        cell.width = 10;
        cell.innerHTML = "&gt;&gt;";
        cell.style.cursor = "pointer";
        cell.title = Titles.year [locale].next;
        cell.onclick = function () {
            time.add (Date.YEAR, 1);
            year_block.innerHTML = time.getFullYear ();
            clearDateGrid ();
            buildDateGrid (body);
        };
        cell.style.border = "1px solid black";
    }

    function createBody () {
        var body = document.createElement ("table");
        body.style.fontSize = fontSize;
        body.style.fontFamily = fontFamily;
        body.cellPadding = 3;
        body.cellSpacing = 1;
        body.bgColor = "#CCCCCC";
        body.border = 0;

        var title = body.insertRow (0);
        title.align = "center";
        title.bgColor = "#3366CC";
        title.style.color = "white";
        title.style.cursor = "default";
        var week_space = title.insertCell (0);
        week_space.innerHTML = Date.Week [locale];
        week_space.style.color = "#CCCCCC";
        week_space.style.fontWeight = "bold";
        week_space.width = "30";
        week_space.nowrap = "true";
        for (var i = 1; i <= 7; i ++) {
            var cell = title.insertCell (i);
            cell.style.fontWeight = "bold";
            cell.innerHTML = Date.WeekTitles [locale] [i - 1];
            if (i == 1 || i == 7) cell.style.color = "red";
        }
        buildDateGrid (body);
        /*
         var area = document.createElement ("textarea");
         area.value = body.innerHTML;
         document.body.appendChild (area);
         */
        return body;
    }

    function clearDateGrid () {
        while (body.rows.length > 1) body.deleteRow (1);
    }

    function buildDateGrid (body) {
        var date = new Date (time.getFullYear (), time.getMonth (), time.getDate ());
        if (arguments [1]) date.setMonth (arguments [1]);
        var month = date.getMonth ();

        date.setDate (1);
        var week = date.getWeekOfYear ();
        var weeks = date.getWeeksInMonth ();
        date.add (Date.DAY_OF_MONTH, -date.getDay ());
        for (var i = 0; i < weeks; i ++) {
            var tr = body.insertRow (body.rows.length);
            tr.align = "center";
            tr.bgColor = "white";
            var week_space = tr.insertCell (0);
            week_space.align = "right";
            week_space.innerHTML = week + i;
            week_space.style.color = "#CCCCCC";

            for (var j = 0; j < 7; j ++) {
                var cell = tr.insertCell (j + 1);
                cell.style.fontSize = fontSize;
                cell.style.fontFamily = fontFamily;
                cell.style.cursor = "pointer";
                cell.innerHTML = date.getDate ();
                if (date.getMonth () != month)
                    cell.style.color = "#CCCCCC";
                else {
                    cell.onmouseover = function (event) {
                        event = event ? event : window.event;
                        if (!event.target) event.target = event.srcElement;
                        event.target.style.backgroundColor = "#CCCCFF";
                    };
                    cell.onmouseout = function (event) {
                        event = event ? event : window.event;
                        if (!event.target) event.target = event.srcElement;
                        event.target.style.backgroundColor = "";
                    };
                    if (j == 0 || j == 6) cell.style.color = "red";
                    if (date.format () == today.format ()) {
                        cell.style.fontWeight = "bold";
                        cell.style.color = "blue";
                    }
                }

                cell.onclick = function (event) {
                    if (!event) event = window.event;
                    if (!event.target) event.target = event.srcElement;
                    self.date = event.target.date;
                    self.close ();
                };
                cell.title = date.format ();
                cell.date = new Date (date.getFullYear (), date.getMonth (), date.getDate ());
                date.add (Date.DAY_OF_MONTH, 1);
            }
        }
    }

    function buildFooter () {
        var footer = document.createElement ("table");
        footer.width = "100%";
        footer.bgColor = "white";
        footer.cellPadding = 3;
        footer.cellSpacing = 1;
        var row = footer.insertRow (0);
        row.style.fontSize = fontSize;
        row.style.fontFamily = fontFamily;
        var cell = row.insertCell (0);
        cell.style.fontWeight = "bold";
        cell.appendChild (document.createTextNode (today_title [locale]));
        cell.appendChild (document.createTextNode (" "));
        var text_today = document.createElement ("span");
        text_today.style.cursor = "pointer";
        text_today.innerHTML = today.format ();
        text_today.onclick = function () {
            self.date = today;
            self.close ();
        };
        cell.appendChild (text_today);

        cell = row.insertCell (1);
        cell.align = "right";

        var clear = document.createElement ("span");
        clear.style.textDecoration = "underline";
        clear.style.cursor = "pointer";
        clear.onclick = function () {
            self.deleteValue ();
        };
        clear.innerHTML = Titles.clear [locale];
        cell.appendChild(clear);

        cell.appendChild (document.createTextNode(" | "));

        var close = document.createElement ("span");
        close.style.textDecoration = "underline";
        close.style.cursor = "pointer";
        close.onclick = function () {
            self.cancel ();
        };
        close.innerHTML = Titles.button [locale];
        cell.appendChild (close);
        return footer;
    }
};